#define LCCTOOLBOX_DLL_IMPORT_LCCTOOLBOX
#include<ALLINALL.hpp>
#include"../componentSlots/componentSlots.hpp"
#include<lencucuCandy.hpp>
using namespace Allinall;
using namespace Lencucu;
using namespace Lencucu::Candy;
using namespace componentSlots;


/////////////////////////////////////////////////////////////
typedef glm::ivec2 vec2;// now the unit is pixel
static vec2 global_window_size;
namespace button{
	void move( COM& com, vec2 dis, glm::mat4& transform){
		float x_dis=float(dis.x)/global_window_size.x*2;
		float y_dis=float(-1*dis.y)/global_window_size.y*2;
		transform=glm::translate(transform,glm::vec3(x_dis,y_dis,0));
		float* preOffset=com.extraData.ptras<float>(2);
		preOffset[0]+=x_dis;
		preOffset[1]+=y_dis;
	}
	void moveTo( COM& com, vec2 pos, glm::mat4& transform){
		vec2 pos_now;
		float* preOffset=com.extraData.ptras<float>(2);
		pos_now.x=(1+preOffset[0])/2*global_window_size.x;
		pos_now.y=(1-preOffset[1])/2*global_window_size.y;
		vec2 dis;
		dis.x=pos.x-pos_now.x;
		dis.y=pos.y-pos_now.y;
		move(com,dis,transform);
	}
	void resize( COM& com, vec2 size, glm::mat4& transform){
		float x_len_to=2.0f*/*rate*/size.x/global_window_size.x/*rate*/;
		float y_len_to=2.0f*/*rate*/size.y/global_window_size.y/*rate*/;
		float* preSize=com.extraData.ptras<float>();
		float* preOffset=com.extraData.ptras<float>(2);
		// back to originPos
		transform=glm::translate(transform,glm::vec3(preOffset[0]*-1,preOffset[1]*-1,0));
		// resize
		transform=glm::scale(transform,glm::vec3(x_len_to/preSize[0],y_len_to/preSize[1],0));
		// back to prePos
		transform=glm::translate(transform,glm::vec3(preOffset[0],preOffset[1],0));
		preSize[0]=x_len_to;
		preSize[1]=y_len_to;
	}
	snote_(hovering,);
	snote_(justPressed,);
	snote_(holding,);
	snote_(justReleased,);
	void initCom(COM&com,vec2 pos,vec2 size){
		com.abilitys.insert(hovering);
		com.abilitys.insert(justPressed);
		com.abilitys.insert(holding);
		com.abilitys.insert(justReleased);
		GenUnit::GenRectangle(com.display);
		com.extraData.alloc(sizeof(float)*4);
		com.extraData.ptras<float>()[0]=1;
		com.extraData.ptras<float>()[1]=1;
		com.extraData.ptras<float>()[2]=0;
		com.extraData.ptras<float>()[3]=0;
		resize(com,size,com.display.uAtb.nodeTransform);
		moveTo(com,pos,com.display.uAtb.transform);
	}
};
/////////////////////////////////////////////////////////////


allinall* AIA_p=nullptr;
lencucu* lcc_p=nullptr;
coms_T* coms_p=nullptr;
note_(mainWin,);


void sizeCallback(GLFWwindow*,int width,int height){
	///////////////////////////
	global_window_size.x=width;
	global_window_size.y=height;
	///////////////////////////
}

void badabingbadaboom(){
	note_(theButton,);
	auto& Env=lcc_p->getRefpEnv();
	auto& GLC=lcc_p->getRefpGLC();
	auto& DS=lcc_p->getRefpDS();
	global_window_size.x=800;
	global_window_size.y=800;

	auto& theCOM=coms_p->insert(theButton).first->Pag;
	button::initCom(theCOM,vec2{50,50},vec2{100,100});
	DataPacket dp;
	dp.unitline_p=&(theCOM.display);
	ShaderPacket sp;
	sp.vtx.combineStr(AIA_p->programPath.ptr(),"../../extension/demo_frame/carry/vtx.glsl");
	sp.frg.combineStr(AIA_p->programPath.ptr(),"../../extension/demo_frame/carry/frg.glsl");

	Env->addwin_on(mainWin,global_window_size.x,global_window_size.y);
	glfwSetWindowSizeCallback(Env->focus(mainWin)->p,sizeCallback);
	Candy::readPacket(*DS,*GLC,dp,sp);
	// {ready the COM}
	GLC->useShader(sp.shader);
	Env->render([&]{
		static int count=1;
		static int op=1;
		if(count==0) op=1;
		if(count==global_window_size.x) op=-1;
		count+=op;
		button::moveTo(theCOM,vec2{count,count},GLC->uniformBuffEmbed(dp.buffer)->transform);
		glClear(GL_COLOR_BUFFER_BIT);
		GLC->draw(AIA_AUTO,dp.array);
		Env->swapBuffers();
		Env->pollEvents();
	});
	Env->rmwin(mainWin);
	// cause it's load in dll's mem,
	// so it should be release in here,
	// else when release lcc & glfw call destroy will 
	// occur error cause can't find the mem where store this window
	theCOM.abilitys.clear();// here seem like the new glfwwindow, also mem problem
}


__shakeShake_(AIAPtr){
	AIA_p=ptras<allinall>(AIAPtr);

	snote_(lencucuHolderType,);snote_(lencucuHolderVar,);
	snote_(componentSlotsType,);snote_(componentSlotsVar,);
	AIA_p->mess.surround(lencucuHolderType);
	lcc_p=*ptras<lencucu*>(AIA_p->mess.var_address(lencucuHolderVar));
	AIA_p->mess.surround(componentSlotsType);
	coms_p=*ptras<coms_T*>(AIA_p->mess.var_address(componentSlotsVar));

	badabingbadaboom();
}